package com.vietnam.power.util;

import java.io.Serializable;
import java.util.Arrays;

import org.apache.log4j.Logger;
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

import com.vietnam.power.dao.IAuditUpdateTable;
import com.vietnam.power.domain.UserPrinciple;

public class AuditTrailInterceptor extends EmptyInterceptor {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private static Logger logger = Logger.getLogger(AuditTrailInterceptor.class);

	/**
	 * when a new entity is first saved, the onSave method is called
	 */
	@Override
	public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
		logger.debug("add more info when creating new record");
		if (entity instanceof IAuditUpdateTable) {
			Authentication auth = SecurityContextHolder.getContext().getAuthentication();
			if (auth == null || auth instanceof AnonymousAuthenticationToken) {
				// from client, hard code timezone =vietnam
				//setValue(state, propertyNames, "updatedDate", DateTimeUtil.getCurrentDateByTimezone(GeneralConstant.VIET_NAM_TIMEZONE));
				//setValue(state, propertyNames, "createdDate", DateTimeUtil.getCurrentDateByTimezone(GeneralConstant.VIET_NAM_TIMEZONE));
			} else {
				UserPrinciple userPrinciple = (UserPrinciple) auth.getPrincipal();
				setValue(state, propertyNames, "createdDate", DateTimeUtil.getCurrentDateByTimezone(userPrinciple.getTimezone()));
				//setValue(state, propertyNames, "userInfo", new UserInfo(userPrinciple.getId()));
			}
			return true;
		}
		return false;
	}

	/**
	 * if an existing entity is updated, onFlushDirty is called
	 */
	@Override
	public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
		logger.debug("add more info when update a existed record");

		if (entity instanceof IAuditUpdateTable) {
			Authentication auth = SecurityContextHolder.getContext().getAuthentication();
			if (auth == null || auth instanceof AnonymousAuthenticationToken) {
				// from client, hard code timezone =vietnam
			//	setValue(currentState, propertyNames, "updatedDate", DateTimeUtil.getCurrentDateByTimezone(GeneralConstant.VIET_NAM_TIMEZONE));
			} else {
				UserPrinciple userPrinciple = (UserPrinciple) auth.getPrincipal();
				setValue(currentState, propertyNames, "updatedDate", DateTimeUtil.getCurrentDateByTimezone(userPrinciple.getTimezone()));
			}
			return true;
		}
		return false;
	}

	/**
	 * Loops through the array of state objects and returns the AuditTrail instance.
	 * 
	 * @param currentState
	 *            the current state
	 * @param propertyNames
	 *            the property names
	 * @param propertyToSet
	 *            the property to set
	 * @param value
	 *            the value
	 */
	private void setValue(Object[] currentState, String[] propertyNames, String propertyToSet, Object value) {
		int index = Arrays.asList(propertyNames).indexOf(propertyToSet);
		if (index >= 0) {
			currentState[index] = value;
		}
	}
}
